package com.pj.current.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.pj.utils.sg.AjaxError;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaHttpMethod;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.util.SaResult;

/**
 * 演示模式的拦截器（如果你不准备搭建演示程序，可以删除此配置类） 
 * <p> 使用方法：
 * 	配置文件里增加以下配置： 
 * 		per=true 
 *  即可打开
 * @author kong 
 */
@Configuration
@ConditionalOnProperty("per")
public class PerformConfigure implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    	System.out.println("\n---------------------- 演示模式启动 \n");
        registry.addInterceptor(new SaInterceptor(handler -> {
        	// 演示模式校验 
			SaRouter.match(
					// 管理员 
					"/admin/add", "/admin/delete", "/admin/deleteByIds", "/admin/update", "/admin/updatePassword",
					"/admin/updateAvatar", "/admin/updateStatus", "/admin/updateRole", "/admin/updateInfo",

					// 修改密码
					"/AdminPassword/update",

					// 管理员登录日志
					"/SpAdminLogin/delete", "/SpAdminLogin/deleteByIds",

					// 全局日志
					"/SgApilog/delete", "/SgApilog/deleteByIds", "/SgApilog/deleteByStartEnd",

					// 全局配置
					"/SpConfig/add", "/SpConfig/delete", "/SpConfig/deleteByIds", "/SpConfig/update", "/SpConfig/updateConfig",

					// 菜单表
					"/SpMenu/add", "/SpMenu/delete", "/SpMenu/update", "/SpMenu/updateSort",

					// redis
					"/RedisConsole/set", "/RedisConsole/del", "/RedisConsole/updateValue", "/RedisConsole/updateTTL", "/RedisConsole/deleteByKeys",

					// 角色
					"/role/add", "/role/delete", "/role/update",

					// 权限
					"/SpRolePermission/updatePcodeByRid",

					// sql控制台
					"/druid/**", "/druid/sql.html",

					// ------------ 业务代码 ------------

					// 应用管理
					"/SysClient/add", "/SysClient/delete", "/SysClient/deleteByIds", "/SysClient/update", "/SysClient/updateStatus",

					// 应用访问关系
					"/SysClientVisit/add", "/SysClientVisit/delete", "/SysClientVisit/deleteByIds", "/SysClientVisit/update",

					// 登录日志
					"/SysLoginLog/delete", "/SysLoginLog/deleteByIds",

					// 用户管理
					"/SysUser/add",
					"/SysUser/delete", "/SysUser/deleteByIds",
					"/SysUser/unDelete", "/SysUser/unDeleteByIds",
					"/SysUser/realDelete", "/SysUser/realDeleteByIds",
					"/SysUser/update", "/SysUser/updateStatus", "/SysUser/updatePassword",

					// 在线管理
					"/SysUserOnline/logout", "/SysUserOnline/kickout", "/SysUserOnline/logoutByToken", "/SysUserOnline/kickoutByToken",

					// 用户监听
					"/ssp/listen/user/add", "/ssp/listen/user/delete", "/ssp/listen/user/update",
					"/ssp/listen/user/updatePassword", "/ssp/listen/user/get"

					)
				.check(r -> {
					throw new AjaxError("演示模式，不可操作，将项目部署到本地预览即可测试此功能");
				})
				;
        })).addPathPatterns("/**").order(-1000); 
    }
    
    /**
     * 注册 [Sa-Token全局过滤器] 
     */
    @Bean
    @Order(-1000)
    public SaServletFilter getSaServletFilterForDruid() {
        return new SaServletFilter()
        		// 拦截与排除 path 
        		.addInclude("/druid/**", "/druid/sql.html")
        		
        		// 全局认证函数 
        		.setAuth(obj -> {
        			// ... 
        			throw new AjaxError("演示模式下不提供 druid 控制台");
        		})
        		
        		// 异常处理函数  
        		.setError(e -> {
        			return SaResult.error(e.getMessage());
        		})
        		
        		// 前置函数：在每次认证函数之前执行
        		.setBeforeAuth(obj -> {
        			// ---------- 设置跨域响应头 ----------
        			SaHolder.getResponse()
        			// 允许指定域访问跨域资源
        			.setHeader("Access-Control-Allow-Origin", "*")
        			// 允许所有请求方式
        			.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
        			// 有效时间
        			.setHeader("Access-Control-Max-Age", "3600")
        			// 允许的header参数
        			.setHeader("Access-Control-Allow-Headers", "*");
        			
        			// 如果是预检请求，则立即返回到前端 
        			SaRouter.match(SaHttpMethod.OPTIONS)
        				.free(r -> System.out.println("--------OPTIONS预检请求，不做处理"))
        				.back();
        		})
        		;
    }
    
}
